home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-11-26 | 4.8 KB | 259 lines | [TEXT/CWIE] |
- /*************************************************************************************************
- *
- *
- * ObjectMacZapp -- a standard Mac OOP application template
- *
- *
- *
- * ZThread.cpp -- an object that implements a single thread of execution
- *
- *
- *
- *
- *
- * © 1996, Graham Cox
- *
- *
- *
- *
- *************************************************************************************************/
-
-
- #include "ZThread.h"
- #include "ZThreadedApplication.h"
-
-
-
- // Constructor
- ZThread::ZThread( long doPeriod, Size stackSize )
- {
- // Initialiase data members
- fDone = FALSE;
- itsID = kNoThreadID;
- itsStack = stackSize;
- itsPeriod = doPeriod;
- }
-
-
- // Destructor
- ZThread::~ZThread()
- {
- // If the thread is running then kill it
- if( itsID != kNoThreadID )
- {
- Terminate();
- }
- }
-
-
- // ThreadEntry()
- void ZThread::ThreadEntry()
- {
- while( !IsDone() )
- {
- // Call Do()
- Do();
-
- // and then sleep for itsPeriod ticks
- SleepTicks( itsPeriod );
- }
-
- itsID = kNoThreadID;
- }
-
-
- // IsDone()
- inline Boolean ZThread::IsDone()
- {
- return fDone;
- }
-
-
- // SetDoPeriod()
- void ZThread::SetDoPeriod( long doPeriod )
- {
- itsPeriod = doPeriod;
- }
-
-
- // Start
- void ZThread::Start()
- {
- // If we already have a thread but it's just stopped, call restart
- if( itsID != kNoThreadID )
- {
- Restart();
- }
- else
- {
- // Get a new thread
- FailOSErr( NewThread( kCooperativeThread,
- (ThreadEntryProcPtr)(&ThreadEntryGlue),
- this,
- itsStack,
- kCreateIfNeeded,
- NULL,
- &itsID ) );
-
- // Install our custom context switchers...
-
- // ... before we're switched in...
- FailOSErr( SetThreadSwitcher( itsID, (ThreadSwitchProcPtr)(&SwitchingInGlue), this, TRUE ) );
-
- // ... and before we're switched out
- FailOSErr( SetThreadSwitcher( itsID, (ThreadSwitchProcPtr)(&SwitchingOutGlue), this, FALSE ) );
- }
- }
-
-
- // Stop()
- OSErr ZThread::Stop()
- {
- if( gMacHasThreadManager )
- {
- return SetThreadState( itsID, kStoppedThreadState, kNoThreadID );
- }
- else
- {
- return paramErr;
- }
- }
-
-
- // Restart()
- OSErr ZThread::Restart()
- {
- if( gMacHasThreadManager )
- {
- return SetThreadState( itsID, kReadyThreadState, kNoThreadID );
- }
- else
- {
- return paramErr;
- }
- }
-
-
- // Terminate()
- void ZThread::Terminate( Boolean fReturnToPool )
- {
- // Stop the thread
- Stop();
-
- if( gMacHasThreadManager )
- {
- // Dispose of it
- DisposeThread( itsID, NULL, fReturnToPool );
- }
-
- // Set itsID so that we can't do anything else to this thread
- itsID = kNoThreadID;
- }
-
-
- // GetState() returns current thread state in *pState
- // The states are defined in Threads.h but can be a bit confusing.
- //
- // Basically my understanding is:
- //
- // - kReadyThreadState means that the thread is ready to run but is not the current
- // thread. Normal running threads will return this if GetState() is called from
- // another thread.
- //
- // - kStoppedThreadState means that the thread has been stopped by a Stop() instruction.
- //
- // - kRunningThreadState means that the thread is running *and* is the current thread.
- // GetState() will return this if it's called from within Do() say.
- //
- ThreadState ZThread::GetState()
- {
- if( (itsID != kNoThreadID) && gMacHasThreadManager )
- {
- ThreadState state;
- FailOSErr( GetThreadState( itsID, &state ) );
- return state;
- }
- else
- {
- return kStoppedThreadState;
- }
- }
-
-
- // SleepTicks()
- void ZThread::SleepTicks( long ticksToSleep )
- {
- long lSleepTicks = TickCount() + ticksToSleep;
-
- if( gMacHasThreadManager )
- {
- do {
- YieldToAnyThread();
- } while( TickCount() < lSleepTicks );
- }
- }
-
-
- // Glue functions not part of ZThread
-
- /******************************************************************************
- ThreadEntryGlue
- ******************************************************************************/
-
- pascal void * ThreadEntryGlue( ZThread* me )
- {
- // Trap exceptions - if an exception runs off the top of the
- // thread stack we'll be in *real* trouble!
- try
- {
- me->ThreadEntry();
- }
- catch(OSErr err)
- {
- }
-
- return NULL;
- }
-
- /******************************************************************************
- SwitchingInGlue
- ******************************************************************************/
-
- pascal void SwitchingInGlue( ThreadID threadBeingSwitched, ZThread* me )
- {
- me->SwitchingIn();
- }
-
- /******************************************************************************
- SwitchingOutGlue
- ******************************************************************************/
-
- pascal void SwitchingOutGlue( ThreadID threadBeingSwitched, ZThread* me )
- {
- me->SwitchingOut();
- }
-
-
- // Utility function - yield for lTicks ticks
- void YieldTicks( long lTicks )
- {
- if( gMacHasThreadManager )
- {
- long targetTicks = TickCount() + lTicks;
- while( TickCount() < targetTicks )
- {
- YieldToAnyThread();
- }
- }
- }
-
-
- // Utility function - safe yield
- void SafeYield()
- {
- if( gMacHasThreadManager )
- YieldToAnyThread();
- }
-
-
-